package com.boarsoft.boar.code.agent;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.boarsoft.boar.agent.AgentServiceImpl;
import com.boarsoft.boar.code.agent.service.ScmService;
import com.boarsoft.common.Util;

public class GitScmServiceImpl implements ScmService {
	private Logger log = LoggerFactory.getLogger(GitScmServiceImpl.class);

	private String username;
	private String password;
	private String path;
	@Autowired
	private AgentServiceImpl agentService;
	private UsernamePasswordCredentialsProvider upcp;

	@PostConstruct
	public void init() {
		upcp = new UsernamePasswordCredentialsProvider(username, password);
	}

	@Override
	public List<String> branches(String uri) {
		List<String> rLt = new ArrayList<>();
		Git git = null;
		try {
			// 远程分支的引用前缀
			git = Git.cloneRepository().setURI(uri)//
					.setCredentialsProvider(upcp)//
					.setCloneAllBranches(true).call();
			// 获取Fetch结果对象
			FetchResult fr = git.fetch()//
					.setCredentialsProvider(upcp)//
					.setRefSpecs(new RefSpec("refs/remotes/origin/*")).call();
			// 获取远程分支的引用列表
			List<Ref> refLt = (List<Ref>) fr.getAdvertisedRefs();
			// 遍历所有分支并输出名称
			for (Ref branch : refLt) {
				rLt.add(branch.getName());
			}
		} catch (GitAPIException e) {
			log.error("Error on get branches of {}", uri, e);
		} finally {
			if (git != null) {
				git.close();
			}
		}
		return rLt;
	}

	@Override
	public String pull(String uri, String branch) {
		try {
			return pullByShell(uri, branch);
		}catch (Throwable e){
			e.printStackTrace();
		}
		return null;
	}
	public String pullByJGit(String uri, String branch) {
		String tp = new StringBuilder(path)//
				.append(uri.substring(uri.lastIndexOf("/")).replace(".git", ""))//
				.append("/").append(branch).toString();
		log.info("Pull source code from {} to {}", uri, tp);
		Git git = null;
		try {
			File tf = new File(tp);
			if (tf.exists()) {
				git = Git.open(new File(tp));
			} else {
				git = Git.cloneRepository().setURI(uri)//
						.setDirectory(new File(tp))//
						.setCredentialsProvider(upcp).call();
				git.checkout().setName(branch).call();
			}
			git.pull().call();
		} catch (JGitInternalException e) {
			String m = e.getMessage();
			if (Util.strIsNotEmpty(m) && m.endsWith("already exists and is not an empty directory")) {

			}
		} catch (Exception e) {
			log.error("Error on pull branch {} from {}", branch, uri, e);
		} finally {
			if (git != null) {
				git.close();
			}
		}
		return tp;

	}
	public String pullByShell(String uri, String branch) throws IOException, InterruptedException {
		String tp = new StringBuilder(path)//
				.append(uri.substring(uri.lastIndexOf("/")).replace(".git", ""))//
				.append("/").append(branch).toString();
		String proj=uri.substring(uri.lastIndexOf("/")+1);
		String shell="sh ./shell/pull.sh "+tp+ " "+ proj + " " + uri + " "+ branch;
		agentService.executeShell(shell);
		return tp;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

}
